<?php
/**
 * Created by PhpStorm.
 * Author: 黑瞎子
 * Date: 2018/3/18
 * Time: 13:59
 */

namespace app\api\service;


use app\lib\enum\ScopeEnum;
use app\lib\exception\ForbiddenException;
use app\lib\exception\TokenException;
use think\Cache;
use think\Exception;
use think\Request;

class Token
{
    /*
     * 生成令牌，令牌由3个字符串md5加密而成
     * */
    public static function generateToken(){
        //32个字符组成一组随机字符串
        $randChars = getRandChar(32);
        //时间戳 $_SERVER['REQUEST_TIME'] 得到请求开始时的时间戳
        $timestamp = $_SERVER['REQUEST_TIME'];
        //salt 盐
        $salt = config('secure.token_salt');

        return md5($randChars.$timestamp.$salt);
    }

    //通过Token获取缓存中某个key的值
    public static function getCurrentTokenVar($key){
        $token = Request::instance()->header('token');
        $var = Cache::get($token);
        if (!$var){
            throw new TokenException();
        }else{
            if (!is_array($var)){
                $var = json_decode($var, true);
            }
            if (array_key_exists($key, $var)){
                return $var[$key];
            }else{
                throw new Exception('尝试获取的Token变量不存在');
            }
        }
    }

    //通过客户端的Token获取uid
    public static function getCurrentUid(){
        $uid = self::getCurrentTokenVar('uid');
        return $uid;
    }

    //权限限制-初级以上权限才能访问
    public static function needPrimaryScope(){
        $scope = self::getCurrentTokenVar('scope');
        if (!$scope){
            throw new TokenException();
        }
        if ($scope >= ScopeEnum::User ){
            return true;
        }else{
            throw new ForbiddenException();
        }
    }

    //权限限制-只能用户访问
    public static function needExclusiveScope(){
        $scope = self::getCurrentTokenVar('scope');
        if (!$scope){
            throw new TokenException();
        }
        if ($scope == ScopeEnum::User ){
            return true;
        }else{
            throw new ForbiddenException();
        }
    }

    //验证订单用户是否是Token用户
    public static function isValidOperate($checkedUID){
        if (!$checkedUID){
            throw new Exception('检测UID时必须传入一个被检测UID');
        }
        $currentOperateUID = self::getCurrentUid();
        if ($currentOperateUID == $checkedUID ){
            return true;
        }
        return false;
    }

    //查看token是否存在缓存中
    public static function verifyToken($token){
        $exist = Cache::get($token);
        if ($exist){
            return true;
        }else{
            return false;
        }
    }
}